<template>
  <div ref="pageViewer" class="page-viewer" :class="{'show':visible}">
    <div class="loading-mask" :class="{'show':isRenderring}">
      <i class="fdx-icon-loading loading-icon"></i>
    </div>
    <canvas :id="`pageViewerCanvas_${pageIndex}`" class="viewer-canvas" ref="pageViewerCanvas"
      :style="{'transform':`scale(${viewRoom},${viewRoom}) translate(${posX}px, ${posY}px)`, 'zIndex':(viewRoom===1?0:999)}"></canvas>
  </div>
</template>

<script>
export default {
  props: {
    pdfDocument: {
      type: Object,
      default: null
    },
    pageIndex: {
      type: Number,
      default: 0
    },
    visible: {
      type: Boolean,
      default: true
    },
    zoom: {
      type: Number,
      default: 1
    },
    posX: {
      type: Number,
      default: 0
    },
    posY: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      pdfPage: null,
      isRenderring: false,
      viewRoom: 1
    }
  },
  created() {
    this.viewRoom = this.zoom
  },
  methods: {
    async getPDFPage(pageIndex) {
      if (this.pdfPage) {
        return this.pdfPage
      }
      var pdfDoc = this.pdfDocument
      if (!pdfDoc) {
        return null
      }
      if (pageIndex > this.pageCount) {
        return null
      }
      this.pdfPage = await pdfDoc.getPage(pageIndex)
      return this.pdfPage
    },
    async renderPDFPage() {
      this.isRenderring = true
      var pdfPage = await this.getPDFPage(this.pageIndex)
      if (!pdfPage) {
        this.isRenderring = false
        return
      }
      var canvas = this.$refs.pageViewerCanvas
      var ctx = canvas.getContext('2d')

      let dpr = window.devicePixelRatio || 1
      let bsr =
        ctx.webkitBackingStorePixelRatio ||
        ctx.mozBackingStorePixelRatio ||
        ctx.msBackingStorePixelRatio ||
        ctx.oBackingStorePixelRatio ||
        ctx.backingStorePixelRatio || 1
      let ratio = dpr / bsr
      var viewport = pdfPage.getViewport(
        this.$refs.pageViewer.clientWidth / pdfPage.getViewport(1).width
      )

      canvas.width = viewport.width * ratio
      canvas.height = viewport.height * ratio

      canvas.style.width = viewport.width + 'px'
      canvas.style.height = viewport.height + 'px'

      ctx.setTransform(ratio, 0, 0, ratio, 0, 0)

      var renderTask = pdfPage.render({
        canvasContext: ctx,
        viewport: viewport
      })
      this.isRenderring = false
      return renderTask.promise
    },
    async show() {
      var pdfPage = this.pdfPage
      if (!pdfPage) {
        pdfPage = await this.renderPDFPage()
      }
      if (!pdfPage) {
        return
      }
      this.viewRoom = 1
      this.posX = this.posY = 0
      this.visible = true
    },
    hide() {
      this.visible = false
    },
    getCanvas() {
      return this.$refs.pageViewerCanvas
    }
  },
  watch: {
    zoom(newVal) {
      this.viewRoom = newVal
      if (newVal === 1) {
        this.posX = this.posY = 0
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.page-viewer {
  display:none;
  flex-grow: 1;
  position: relative;
  opacity: 0;

  &.show {
    display: flex;
    opacity: 1;
  }

  .loading-mask {
    position: absolute;
    left: 0px;
    top: 0px;
    bottom: 0px;
    right: 0px;
    background-color: rgba(0, 0, 0, 0.2);
    flex-flow: column;
    align-items: center;
    justify-content: center;
    padding-bottom: 20px;
    transition: all ease 300ms;
    opacity: 0;
    display: none;
    z-index: -1;

    &.show {
      opacity: 1;
      z-index: 9;
      display: flex;
    }

    .loading-icon {
      &::before {
        font-size: 48px;
      }
    }
  }

  .viewer-canvas {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    transition: all linear 100ms;
  }
}
</style>
